package com.cskaoyan.javase._2inner._3local._4life;
/**
 * 在局部内部类当中被访问的作用域内部的局部变量,应该是一个常量.
 * 主要原因在于:
 * 局部变量和对象的生命周期的冲突
 * 局部变量随着方法出栈被销毁,但对象仍然存在,该对象的成员方法依然会访问局部变量
 * 为了解决这种生命周期的冲突
 * JVM会在创建 访问了作用域局部变量的 局部内部类对象时
 * 将该局部变量作为局部内部类对象的成员变量
 *
 * 在很多时候,在解决问题的时候,解决问题所使用的方案,它可能本身就是一个问题
 * 一旦用拷贝成员变量的方式解决生命周期的冲突
 * 那就存在成员变量和局部变量取值同步的问题
 * 为了避免这个同步的麻烦,java的设计者干脆禁止修改,使它成为一个常量.
 *
 * @since 11:00
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        EnclosedClazz ec = new EnclosedClazz();
        // 局部变量a就仅存在于该行调用test方法时
        IA inner = ec.test();
        // 对象依然存在,依然能够调用方法,方法中访问了局部变量a,这时去哪里找局部变量a呢?
        inner.testInner();
    }
}
class EnclosedClazz {
    public IA test() {
        // 方法的局部变量a
        int a = 10;
        class Inner implements IA {
            @Override
            public void testInner() {
                System.out.println(a);
                /*
                    如果允许方法能够修改局部变量的取值
                    代码上看起来是修改了局部变量a的取值
                    但实际上从内存中来说,是修改了自身对象中拷贝的成员变量a的取值
                    这样如果允许修改,就存在"同步"问题
                    需要将成员变量a的取值的修改 同步给方法中的局部变量a
                    如果不同步,就会出现代码逻辑上的错误

                    总之,如果允许修改a的取值,麻烦一大把
                    但是如果不允许修改,就不会出现同步问题,什么麻烦都没有,很舒服
                 */
                // a = 200;
            }
        }
        Inner i = new Inner();
        i.testInner();
        System.out.println(a);
        return new Inner();
    }
}
interface IA{
    void testInner();
}